#pragma once
#include "NodoTemplate.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

template <class T>
class Lista
{
private:
	Nodo<T>* primero;  //puntero al inicio
	Nodo<T>* actual;
public: 
	Lista();
	Lista(Lista *);  //constructor copia
	
	virtual ~Lista();

	Nodo<T>* getPrimero();
	Nodo<T>* getActual();
	void setActual(Nodo<T> *);
    void setPrimero(Nodo<T> *);
	virtual void insertarPrimero(T *);
	virtual int eliminar(string);		
	virtual string toString();
	virtual T * buscar(string);
};


template<class T>
Nodo<T>* Lista<T>::getActual(){
   return actual;


}



template<class T>
Nodo<T>* Lista<T>::getPrimero(){
   return primero;


}

template<class T>
void Lista<T>::setActual(Nodo<T> *act){

actual=act;

}

template<class T>
void Lista<T>::setPrimero(Nodo<T> *prim){

primero=prim;

}





template<class T>
Lista<T>::Lista()
{
	actual = primero = NULL; 
}

template<class T>
Lista<T>::Lista(Lista<T> *list)
{   
	
	list->setActual(list->getPrimero());
	while(list->getActual() != NULL)
	{
		insertarPrimero(new T(list->getActual()->getInfo()));
		list->setActual(list->getActual()->getSigNodo());
	}
}


template<class T>
Lista<T>::~Lista()
{
	while(primero!=NULL)
	{
		actual = primero;
	    primero=primero->getSigNodo();
	    delete actual;
	}

}

template<class T>
void Lista<T>::insertarPrimero(T * c)
{
	if(primero == NULL)
	{
		primero = new Nodo<T>(NULL,c);
		
	}
	else
	{
		actual = new Nodo<T>(primero,c);
		primero = actual;
	}
}

template<class T>
int Lista<T>::eliminar(string codigo){
	
	int ret = 0;
	if(primero!=NULL)
	{
	    actual = primero;
		if(*(primero->getInfo())== codigo)
		{
			primero=primero->getSigNodo();
			delete actual;
		}
		else
		{

			Nodo<T> *aux;
			while(actual->getSigNodo()!=NULL)
			{   
				if(*(actual->getSigNodo()->getInfo())==codigo)
				{
					aux=actual->getSigNodo();
					actual->setSigNodo(actual->getSigNodo()->getSigNodo());
					delete aux;
					ret = 1;
				}
				actual=actual->getSigNodo();
			}
		}
	}
	return ret;
}

template<class T>
string Lista<T>::toString()
{
	stringstream s;
    if(primero==NULL)
    	s<<"la lista esta vacia";

    	actual = primero;
    	while(actual != NULL)
    	{
    		s<<"-----------------------------\n";
			s<< actual->getInfo()->toString()<<endl;
    		actual = actual->getSigNodo();
    	}

    return s.str();
}

template<class T>
T* Lista<T>::buscar(string codigo){

 actual=primero;
	while(actual!=NULL)
	{
		if(*(actual->getInfo())==codigo)
		{
			return (actual->getInfo());
		}

		actual=actual->getSigNodo();
	}
	return NULL;
}